/******************************************************************************

    Copyright (C) 2018 ErisedMedia
    All Rights Reserved.

    This source code and any compilation or derivative thereof is the
    proprietary information of ErisedMedia and is
    confidential in nature.
    Under no circumstances is this software to be exposed to or placed under an
    Open Source License of any type without the expressed written permission of
    ErisedMedia.

******************************************************************************/

/******************************************************************************

    File:   Tools.h
    Brief:  Tools的头文件，工具接口.

******************************************************************************/

/******************************************************************************

    Rev     Date        Author      Comments
--------------------------------------------------------------------------------
    001     20181120    RunyuanYe        Original

--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.

*******************************************************************************/
#ifndef _TOOLS_H_
#define _TOOLS_H_

/******************************************************************************
*
*   INCLUDE FILES
*
******************************************************************************/


/******************************************************************************
*
*   MACROS
*
******************************************************************************/

#define ENABLE_TIME_BENCHMARK_TEST  1

#define ENABLE_PROFILE_TIME_LOCK    1

#if ENABLE_TIME_BENCHMARK_TEST
#define START_PROFILE_TIME(name, info) \
    static ProfileTime name(info); name.StartTime()

#define END_PROFILE_TIME(name) \
    name.EndTime()

#define INTERVAL_PROFILE_TIME(name, info) \
    static ProfileTime name(info); name.FpsIntervalTime()

#define START_PROFILE_TIME_EX(name, info, frame) \
    static ProfileTime name(info, frame); name.StartTime()

#define INTERVAL_PROFILE_TIME_EX(name, info, time) \
    static ProfileTime name(info); name.FpsIntervalTime(time)

#else

#define START_PROFILE_TIME(name, info)

#define END_PROFILE_TIME(name)

#define INTERVAL_PROFILE_TIME(name, info)

#define START_PROFILE_TIME_EX(name, info, frame)

#define INTERVAL_PROFILE_TIME_EX(name, info, time)

#endif

/******************************************************************************
*
*   TYPEDEFS
*
******************************************************************************/


/******************************************************************************
*
*   EXPORT DATA
*
******************************************************************************/


/******************************************************************************
*
*   EXPORT FUNCTION PROTOTYPES
*
******************************************************************************/

/*
    获取时钟Ticks，单位：毫秒

    返回时钟计数
*/
long long GetClockTicks();

/*
    获取时钟Ticks，单位：微秒

    返回时钟计数
*/
long long GetClockTicksEx();

/*
    获取文件大小

    file：为输入的文件

    成功返回文件大小，失败返回负值
*/
int GetFileSize(FILE* file);

/*
    获取文件大小

    fileName：为输入的文件名

    成功返回文件大小，失败返回负值
*/
int GetFileSizeEx(const char* fileName);

#ifdef USE_UUID
/*
    生成UUID

    uuid：输出UUID字符串
*/
void GenerateUUID(char *puuid);

/*
    生成UUID

    uuid：输出UUID字符串
*/
void GenerateUUIDEx(std::string& uuid);
#endif

/*
    获取文件名

    fullFileName： 带目录的完整路径名
    needExt： 是否需要返回文件名的扩展名

    返回获取的文件名
*/
std::string GetFileName(std::string fullFileName, bool needExt=true);

/**
 * @brief Gets filename without extension
 * @param filepath - full file name
 * @return filename without extension
 */
std::string FileNameNoExt(const std::string &filepath);

/*
    把一个long long类型的变量赋值给另一个long long类型的变量

    避免地址不对齐时导致程序崩溃
*/
void LongLongAssign(void* dst, const void* src);

/*
    连接两个路径

    joinpath： 为输出的连接后的路径
    path1： 要连接的第1个路径
    path2： 要连接的第2个路径
*/
void JoinPath(std::string& joinpath, const std::string& path1, const std::string& path2);

/*
    连接两个路径

    path1： 要连接的第1个路径
    path2： 要连接的第2个路径

    返回连接后的路径
*/
std::string JoinPathEx(const std::string& path1, const std::string& path2);

std::vector<std::string> StringSplit(std::string& str, char splitChr);

class ProfileTime
{
public:
    ProfileTime(const char* infoString, int printFrameCount = 50, bool needPrint=true);
    ~ProfileTime();

    void StartTime();

    void EndTime();

    // time: ms
    void FpsIntervalTime(int time = 10000);

    float GetFps() const;
    float GetFrameTime() const;

protected:
    std::string m_infoString;
    long long m_totalTime;
    long long m_frameCount;
    long long m_startTime;
    long long m_endTime;
    int m_printFrameCount;

    long long m_intervalFrameCount;
    long long m_intervalStartTime;
    long long m_intervalEndTime;
    bool m_intervalIsFirst;

    bool m_needPrint;
    float m_fps;
    float m_time;

    #if ENABLE_PROFILE_TIME_LOCK
    std::mutex   m_lock;
    #endif
};

#endif //#ifndef _TOOLS_H_
